package com.laoxu.test.rbacdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.laoxu.test.rbacdemo.common.PageRequest;
import com.laoxu.test.rbacdemo.constant.AppConstant;
import com.laoxu.test.rbacdemo.dao.SysRoleMapper;
import com.laoxu.test.rbacdemo.dao.SysUserRoleMapper;
import com.laoxu.test.rbacdemo.model.SysDeptUsers;
import com.laoxu.test.rbacdemo.model.SysUser;
import com.laoxu.test.rbacdemo.dao.SysUserMapper;
import com.laoxu.test.rbacdemo.model.SysUserRole;
import com.laoxu.test.rbacdemo.service.SysUserRoleService;
import com.laoxu.test.rbacdemo.service.SysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.laoxu.test.rbacdemo.service.UserManager;
import com.laoxu.test.rbacdemo.util.MD5Util;
import com.laoxu.test.rbacdemo.util.SortUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author laoxu
 * @since 2020-08-09
 */
@Slf4j
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Autowired
    private SysUserRoleMapper userRoleMapper;
    @Autowired
    private SysUserRoleService userRoleService;
    @Autowired
    private UserManager userManager;


    @Override
    public SysUser findByName(String username) {
        return baseMapper.findDetail(username);
    }


    @Override
    public IPage<SysUser> findUserDetail(SysUser user, PageRequest request) {
        try {
            Page<SysUser> page = new Page<>();
            SortUtil.handlePageSort(request, page, "userId", AppConstant.ORDER_ASC, false);
            return this.baseMapper.findUserDetail(page, user);
        } catch (Exception e) {
            log.error("查询用户异常", e);
            return null;
        }
    }

    @Override
    @Transactional
    public void updateLoginTime(String username) throws Exception {
        SysUser user = new SysUser();

        this.baseMapper.update(user, new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
        
    }

    @Override
    @Transactional
    public void createUser(SysUser user) throws Exception {
        // 创建用户
        user.setCreateTime(new Date());
        user.setAvatar(SysUser.DEFAULT_AVATAR);
        user.setPassword(MD5Util.encrypt(user.getUsername(), SysUser.DEFAULT_PASSWORD));
        save(user);

        // 保存用户角色
        String[] roles = user.getRoleId().split(StringPool.COMMA);
        setUserRoles(user, roles);
        //查询用户角色
    }

    @Override
    @Transactional
    public void updateUser(SysUser user) throws Exception {
        // 更新用户
        user.setPassword(null);
        user.setUpdateTime(new Date());
        updateById(user);

        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("USER_ID", user.getUserId());
        userRoleMapper.delete(queryWrapper);

        String[] roles = user.getRoleId().split(StringPool.COMMA);
        setUserRoles(user, roles);
    }

    @Override
    @Transactional
    public void deleteUsers(String[] userIds) throws Exception {
        List<String> list = Arrays.asList(userIds);

        removeByIds(list);

        // 删除用户角色
        this.userRoleService.deleteUserRolesByUserId(userIds);
    }

    @Override
    @Transactional
    public void updateProfile(SysUser user) throws Exception {
        updateById(user);
    }

    @Override
    @Transactional
    public void updateAvatar(String username, String avatar) throws Exception {
        SysUser user = new SysUser();
        user.setAvatar(avatar);

        this.baseMapper.update(user, new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
    }

    @Override
    @Transactional
    public void updatePassword(String username, String password) throws Exception {
        SysUser user = new SysUser();
        user.setPassword(MD5Util.encrypt(username, password));

        this.baseMapper.update(user, new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
    }

    @Override
    @Transactional
    public void regist(String username, String password) throws Exception {
        SysUser user = new SysUser();
        user.setPassword(MD5Util.encrypt(username, password));
        user.setUsername(username);
        user.setCreateTime(new Date());
        user.setStatus(SysUser.STATUS_LOCK);
        user.setGender(SysUser.SEX_UNKNOW);
        user.setAvatar(SysUser.DEFAULT_AVATAR);
        user.setDescription("注册用户");
        this.save(user);

        SysUserRole ur = new SysUserRole();
        ur.setUserId(user.getUserId());
        ur.setRoleId(2L); // 注册用户角色 ID
        this.userRoleMapper.insert(ur);
    }

    @Override
    @Transactional
    public void resetPassword(String[] usernames) throws Exception {
        for (String username : usernames) {

            SysUser user = new SysUser();
            user.setPassword(MD5Util.encrypt(username, SysUser.DEFAULT_PASSWORD));

            this.baseMapper.update(user, new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
        }

    }

    private void setUserRoles(SysUser user, String[] roles) {
        Arrays.stream(roles).forEach(roleId -> {
            SysUserRole ur = new SysUserRole();
            ur.setUserId(user.getUserId());
            ur.setRoleId(Long.valueOf(roleId));
            this.userRoleMapper.insert(ur);
        });
    }
    @Override
    public String findSubordinates(Long deptId){
        return baseMapper.findSubordinates(deptId);
    }

    @Override
    public List<SysDeptUsers> findSubordinatesMap(){
        return baseMapper.findSubordinatesMap();
    }
}
